﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Collections.Specialized;

namespace NLBS.Urls
{
    /// <summary>
    /// A set of Locations
    /// </summary>
    public class LocationSet : IEnumerable
    {
        ListDictionary locations = new ListDictionary();

        /// <summary>
        /// Adds a Location to this LocationSet
        /// </summary>
        /// <param name="name">Name of the location to add</param>
        /// <param name="location">Location to add</param>
        public void Add(string name, Location location)
        {
            locations[name.ToLower()] = location;
        }

        /// <summary>
        /// Returns the path of the Location matching the given name
        /// </summary>
        /// <param name="name">Name of the Location</param>
        /// <returns>Path of the matching Location</returns>
        public string this[string name]
        {
            get
            {
                return ((Location)locations[name.ToLower()]).Path;
            }
        }

        /// <summary>
        /// Returns the Locations within this LocationSet matching the given path
        /// </summary>
        /// <param name="path">Url path to match</param>
        /// <returns>Locations matching the given Url path, or null</returns>
        public IList<Location> FindLocationsByPath(string path)
        {
            List<Location> matchingLocations = new List<Location>();

            foreach (Location loc in locations.Values)
            {
                if (loc.IsMatch(path))
                {
                    matchingLocations.Add(loc);
                }
            }

            return matchingLocations;
        }

        /// <summary>
        /// Returns the Location matching the given name
        /// </summary>
        /// <param name="name">Name of the Location</param>
        /// <returns>Location matching the given name, or null</returns>
        public Location FindLocationByName(string name)
        {
            name = name.ToLower();
            foreach (string key in locations.Keys)
            {
                if (key == name)
                    return this.locations[name] as Location;
            }

            return null;
        }

        #region IEnumerable Members

        /// <summary>
        /// Returns an enumerator that iterates over the Locations in this LocationSet
        /// </summary>
        /// <returns>Enumerator that iterates over the Locations in this LocationSet</returns>
        public IEnumerator GetEnumerator()
        {
            return locations.GetEnumerator();
        }

        #endregion

        /// <summary>
        /// Regex pattern matching Url paths that can be processed by this LocationSet
        /// </summary>
        public string Filter
        {
            get
            {
                StringBuilder sb = new StringBuilder();
                foreach (Location loc in locations.Values)
                {
                    if (loc.Exclude && loc.Path != null && loc.Path.Length > 1)
                    {
                        sb.Append("|" + loc.Path);
                    }
                }

                //return sb.ToString();

                string text = sb.ToString();
                if (text != null && text.Length > 0)
                    text = text.Substring(1);

                return string.Format("^({0})", text);
            }
        }
    }
}
